package org.hairball.vis;

import org.hairball.graph.EdgeVisitor;
import org.hairball.graph.HairballGraph;
import org.hairball.graph.NodeVisitor;

public class GraphmlCreator implements GraphMarkupCreator {

    public String createFromGraph(String graphName, HairballGraph graph) {
        String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!-- Created by Hairball. See http://code.google.com/p/hairball -->\n" +
                "<graphml\n" +
                "        xmlns=\"http://graphml.graphdrawing.org/xmlns/graphml\"\n" +
                "        xmlns:y=\"http://www.yworks.com/xml/graphml\"\n" +
                "        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
                "        xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd\">\n" +
                "    <key id=\"d0\" for=\"node\" yfiles.type=\"nodegraphics\"/>\n" +
                "    <key id=\"d1\" for=\"edge\" yfiles.type=\"edgegraphics\"/>\n" +
                "    <graph id=\"G\" edgedefault=\"directed\">\n";
        String footer = "    </graph>\n" + "</graphml>\n";
        return header + createNodes(graph) + createEdges(graph) + footer;
    }

    private String createEdges(HairballGraph graph) {
        final StringBuilder builder = new StringBuilder();

        graph.visitEdges(new EdgeVisitor() {

            public void visit(String fromNode, String toNode, String edgeType) {
                String id = fromNode + ":" + toNode + ":" + edgeType;
                builder.append("        <edge id=\"" + id + "\" source=\"" + fromNode + "\" target=\"" + toNode + "\">\n" +
                        "            <data key=\"d1\">\n" +
                        "                <y:PolyLineEdge>\n" +
                        "                    <y:Arrows source=\"none\" target=\"standard\"/>\n" +
                        "                    <y:EdgeLabel>" + edgeType + "</y:EdgeLabel>\n" +
                        "                </y:PolyLineEdge>\n" +
                        "            </data>\n" +
                        "        </edge>\n");
            }
        });
        return builder.toString();
    }

    private String createNodes(HairballGraph graph) {
        final StringBuilder builder = new StringBuilder();

        graph.visitNodes(new NodeVisitor() {
            public void visit(String node, boolean connected) {
                builder.append(createNode(node));
            }
        });

        return builder.toString();
    }

    private String createNode(String node) {
        return "        <node id=\"" + node + "\">\n" +
                "            <data key=\"d0\">\n" +
                "                <y:ShapeNode>\n" +
                "                    <y:Geometry width=\"100.0\" height=\"30.0\"/>\n" +
                "                    <y:Fill color=\"#DFABAB\" transparent=\"false\"/>\n" +
                "                    <y:BorderStyle type=\"line\" width=\"1.0\" color=\"#000000\"/>\n" +
                "                    <y:NodeLabel fontFamily=\"Dialog\" fontSize=\"12\" fontStyle=\"plain\" textColor=\"#000000\" autoSizePolicy=\"content\">\n" +
                "                        " + node + "\n" +
                "                    </y:NodeLabel>\n" +
                "                    <y:Shape type=\"roundrectangle\"/>\n" +
                "                </y:ShapeNode>\n" +
                "            </data>\n" +
                "        </node>\n";
    }
}
